// 定义二维码解析结果类型
interface ScanResult {
  /** 原始二维码内容（已解码） */
  raw: string;
  /** 基础URL（不含查询参数） */
  baseUrl: string;
  /** 解析后的参数对象 */
  params: Record<string, string>;
  /** 扫码时间戳（秒） */
  scanTime: number;
}

/**
 * 统一解析二维码的查询参数
 * 该函数根据传入的查询参数（query）决定是处理普通二维码（`q` 参数）还是小程序码（`scene` 参数）。
 *
 * @param query - 请求中传入的查询参数
 * @returns 如果解析成功，返回 ScanResult 对象，否则返回 null
 */
export function parseScanCodeQuery(query: Record<string, string | undefined>): ScanResult | null {
  try {
    // 优先处理普通二维码参数
    if (query.q) {
      return handleRegularQRCode(query);
    }

    // 处理小程序码参数
    if (query.scene) {
      return handleMiniProgramCode(query);
    }

    console.warn('未找到有效二维码参数');
    return null;
  } catch (error) {
    console.error('二维码解析失败:', error);
    return null;
  }
}

/**
 * 处理普通二维码（带 `q` 参数的二维码）
 *
 * @param query - 请求中传入的查询参数
 * @returns 解析后的 ScanResult 对象
 */
function handleRegularQRCode(query: Record<string, string | undefined>): ScanResult {
  const raw = decodeURIComponent(query.q!);

  // 分离基础URL和查询参数
  const [baseUrl, queryString] = raw.split('?', 2);
  const decodedBaseUrl = decodeURIComponent(baseUrl);
  const decodedQueryString = queryString ? decodeURIComponent(queryString) : '';

  return {
    raw,
    // 如果基础URL没有包含协议（如 http://），则返回原始的二维码内容
    baseUrl: decodedBaseUrl && !decodedBaseUrl.includes('://') ? raw : decodedBaseUrl,
    params: parseQueryString(decodedQueryString),
    // 获取扫码时间，若未提供，使用当前时间戳（秒级）
    scanTime: Number(query.scancode_time) || Math.floor(Date.now() / 1000)
  };
}

/**
 * 处理小程序码（带 `scene` 参数的二维码）
 *
 * @param query - 请求中传入的查询参数
 * @returns 解析后的 ScanResult 对象
 */
function handleMiniProgramCode(query: Record<string, string | undefined>): ScanResult {
  const raw = decodeURIComponent(query.scene!);

  return {
    raw,
    baseUrl: '', // 小程序码一般不包含 URL
    params: parseQueryString(raw),
    scanTime: Number(query.scancode_time) || Math.floor(Date.now() / 1000) // 使用扫码时间戳（秒级）
  };
}

/**
 * 解析查询字符串为一个键值对对象
 * 该函数处理URL查询字符串，将其解析为一个对象（例如 "key=value&anotherKey=value2" => { key: "value", anotherKey: "value2" }）
 *
 * @param str - 查询字符串（格式为 `key=value&key2=value2`）
 * @returns 返回解析后的键值对对象
 */
function parseQueryString(str: string): Record<string, string> {
  return str.split('&').reduce((acc, pair) => {
    try {
      const [key, value] = pair.split('=', 2); // 限制分割次数，避免多次 `=` 出现
      if (key) {
        // 处理无值的参数（如 `key`）
        acc[decodeURIComponent(key)] = decodeURIComponent(value || '');
      } else {
        console.warn(`无效的查询参数: ${pair}`);
      }
    } catch (error) {
      console.error('解析查询字符串出错:', error);
    }
    return acc;
  }, {} as Record<string, string>);
}

export default parseScanCodeQuery;
